package jue;

/**
 * 线程的同步-协作
 * 生产者和消费者的问题
 */
public class Demo {
    static class guizi {
        private int size;//数量
        private int num;//容器上限

        public guizi(int num) {
            this.num = num;
        }

        boolean man() {
            return size == num;
        }

        boolean kong() {
            return size == 0;
        }

        void add() {
            synchronized (this) {
                while (this.man()) {

                    try {
                        System.out.println(Thread.currentThread().getName() + "：满了，等待中...");
                        this.wait();
                        System.out.println(Thread.currentThread().getName() + "：被唤醒！");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }

                size++;
                System.out.println(Thread.currentThread().getName() + ":放入面包，剩余数量为：" + size);
                //唤醒所以的线程
                this.notifyAll();//该方法是Object的方法，只能 （1）通过锁对象，（2）在同步代码块中 调用
                Thread.yield();
            }
        }

        void remove() {
            synchronized (this) {
                while (this.kong()) {

                    try {
                        System.out.println(Thread.currentThread().getName() + "：空了，等待中...");
                        this.wait();
                        System.out.println(Thread.currentThread().getName() + "：被唤醒！");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
                size--;
                System.out.println(Thread.currentThread().getName() + ":取出面包，剩余数量为：" + size);
                //唤醒所以的线程
                this.notifyAll();//该方法是Object的方法，只能 （1）通过锁对象，（2）在同步代码块中 调用
                Thread.yield();
            }
        }
    }

    public static void main(String[] args) {
        guizi guizi = new guizi(5);
        for (int k = 1; k <= 5; k++) {
            new Thread(() -> {
                for (int i = 0; i < 100; i++) {
                    guizi.add();
                }
            }, "面包师父" + k).start();

            new Thread(() -> {
                for (int i = 0; i < 100; i++) {
                    guizi.remove();
                }
            }, "店员" + k).start();
        }
    }
}
